/********************************************************************************
 * Copyright(c) 2020-2025 BST All rights reserved.
 * - Filename
 * - Author
 * - Version V1.0.0
 * - Date    2025/11/13
 * - Brief
 * - FunctionList:
 ******************************************************************************
 * History:
 *
 *
 *
 ******************************************************************************
 */
#pragma once

#include <condition_variable>
#include <deque>
#include <mutex>

#include "Lidar.hpp"
#include "TimeUtil.h"
#include "lidar_driver.h"
using namespace robosense::lidar;

class RsLidarAdapter : public lidar::Lidar {
 public:
  RsLidarAdapter(const uint32_t &id, const std::string &ip,
                 const uint16_t &msop_port, const uint16_t &difop_port,
                 const std::string &model);
  ~RsLidarAdapter();
  void start(std::function<void(std::shared_ptr<lpc::LidarProtoPointCloud> &&)>)
      override;
  void stop() override;

 protected:
  const uint32_t _id;
  const std::string _ip;
  const uint16_t _msopPort;
  const uint16_t _difopPort;

 private:
  struct RsPointXYZI {
    float x;
    float y;
    float z;
    uint8_t intensity;
  };
  bool _isExit{true};
  std::string _model;
  TimeUtil::FpsCalc _fps{};
  std::map<std::string, int> _modelMap;
  std::shared_ptr<robosense::lidar::LidarDriver<RsLidarAdapter::RsPointXYZI>> _lidar{nullptr};
  std::shared_ptr<RSDriverParam> _lidarConfig{nullptr};
  std::shared_ptr<std::thread> _lidarFrameThread{nullptr};
  std::mutex _mtx;
  std::condition_variable _condition;
  std::deque<std::shared_ptr<lpc::LidarProtoPointCloud>> _lidarFrameDeque{};
  void processLoop(
      const std::function<void(std::shared_ptr<lpc::LidarProtoPointCloud> &&)>
          &callback);
  void getLidarFrameLoop();
  void lidarFrameCallback(const PointCloudMsg<RsLidarAdapter::RsPointXYZI> &msg);
  void exceptionCallback(const Error &code);
};